package com.viroyal.monitorlib.network.upload;

import android.content.Context;
import android.text.TextUtils;
import android.util.Log;

import com.alibaba.sdk.android.oss.ClientConfiguration;
import com.alibaba.sdk.android.oss.ClientException;
import com.alibaba.sdk.android.oss.OSSClient;
import com.alibaba.sdk.android.oss.ServiceException;
import com.alibaba.sdk.android.oss.callback.OSSCompletedCallback;
import com.alibaba.sdk.android.oss.common.auth.OSSCredentialProvider;
import com.alibaba.sdk.android.oss.common.auth.OSSStsTokenCredentialProvider;
import com.alibaba.sdk.android.oss.model.PutObjectRequest;
import com.alibaba.sdk.android.oss.model.PutObjectResult;
import com.suntiago.baseui.utils.log.Slog;
import com.viroyal.monitorlib.BuildConfig;
import com.viroyal.monitorlib.entity.OssAttributesResponse;
import com.viroyal.monitorlib.network.Api;
import com.viroyal.monitorlib.network.UpdateApi;
import com.viroyal.monitorlib.network.rsp.FileUploadResponse;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1;
import rx.schedulers.Schedulers;

/**
 * 上传文件数据仓库类.
 * <p>
 * Created by yj on 2017/9/26.
 */

public class UploadRepository {
    private static final String TAG = "UploadRepository";
    public static final String ALI_OSS_HOSTNAME = "http://viroyalcampus.oss-cn-shanghai.aliyuncs.com";
    public static final String BUCKET_OTHER = "其他";
    public static final String SCHOOL_NAME = "智慧校园";

    public static void uploadToOss(Context context, String path, String folder, String name, OssAttributesResponse.OssAttributes oss,
                                   ApiCallback callback) {
        File file = new File(path);
        if (!file.exists()) {
            FileUploadResponse r = new FileUploadResponse();
            r.error_code = -1;
            r.error_msg = "文件不存在";
            callback.onResult(r);
            return;
        }
        //根据文件类型判断并加上后缀
        name += getFileExtension(file);
        if (!folder.endsWith("/")) folder += "/";
        name = folder + name;
        //转换百分号编码
//    name = EncryptionUtil.encodeUTF8(name);
        //配置上传信息
        OSSCredentialProvider credentialProvider = new OSSStsTokenCredentialProvider(oss.access_key, oss.secret_key,
                oss.security_token);
        ClientConfiguration conf = new ClientConfiguration();
        conf.setConnectionTimeout(15 * 1000); // 连接超时，默认15秒
        conf.setSocketTimeout(15 * 1000); // socket超时，默认15秒
        conf.setMaxConcurrentRequest(5); // 最大并发请求书，默认5个
        conf.setMaxErrorRetry(2); // 失败后最大重试次数，默认2次
        OSSClient ossClient = new OSSClient(context, oss.endpoint, credentialProvider, conf);
        //下面3个参数依次为bucket名，Object名，上传文件路径
        PutObjectRequest put = new PutObjectRequest(oss.bucket_name, name, path);
        // 异步上传，可以设置进度回调
//        put.setProgressCallback((request, currentSize, totalSize) ->
//                Slog.i("currentSize: " + currentSize + " totalSize: " + totalSize));
        String finalName = name;
        String finalRecallUrl = ALI_OSS_HOSTNAME + "/" + encodeUTF8(finalName);
        ossClient.asyncPutObject(put, new OSSCompletedCallback<PutObjectRequest, PutObjectResult>() {
            @Override
            public void onSuccess(PutObjectRequest request, PutObjectResult result) {
                Slog.i(TAG, "UploadSuccess");
                callback.onResult("成功");
                FileUploadResponse r = new FileUploadResponse();
                r.error_code = 1000;
                r.error_msg = "成功";
                r.extra = finalRecallUrl;
                callback.onResult(r);
            }

            @Override
            public void onFailure(PutObjectRequest request, ClientException clientExcepion, ServiceException
                    serviceException) {
                Slog.i(TAG, "UploadError");
                String error = "上传失败";
                // 请求异常
                if (clientExcepion != null) {
                    // 本地异常如网络异常等
                    clientExcepion.printStackTrace();
                }
                if (serviceException != null) {
                    // 服务异常
                    Log.e("ErrorCode", serviceException.getErrorCode());
                    Log.e("RequestId", serviceException.getRequestId());
                    Log.e("HostId", serviceException.getHostId());
                    Log.e("RawMessage", serviceException.getRawMessage());
                    error = serviceException.getMessage();
                }
                FileUploadResponse r = new FileUploadResponse();
                r.error_code = -3;
                r.error_msg = "上传失败";
                callback.onResult(r);
            }
        });

    }

    public static void upload(Context context, String filePath, String folder, String name, ApiCallback callback) {
        if (!new File(filePath).exists()) {
            FileUploadResponse r = new FileUploadResponse();
            r.error_code = -1;
            r.error_msg = "文件不存在";
            callback.onResult(r);
            Slog.d(TAG, "upload  [context, filePath, folder, name, callback]:文件不存在");

            return;
        }
        if (TextUtils.isEmpty(folder)) {
            folder = BUCKET_OTHER;
        }
        folder = SCHOOL_NAME + "/" + folder;
        //先调用Oss接口获取Oss信息
        String finalFolder = folder;
        getOssInfo(info -> {
            if (info.error_code == 1000) {
                uploadToOss(context, filePath, finalFolder, name, info.extra, callback);
            } else {
                FileUploadResponse f = new FileUploadResponse();
                f.error_code = info.error_code;
                f.error_msg = info.error_msg;
                callback.onResult(f);
            }

        });

    }

    public static void getOssInfo(Action1<OssAttributesResponse> callback) {
        //https://139.196.3.125:8443
        //abcdefghijkopqrstuvwxyz123456
        Slog.d(TAG,"getOssInfo :");
        Api.get().getApi(UpdateApi.class)
                .getOssInfo(BuildConfig.API_HOST + "home/ossinfo",
                        "tUnmjGTZglI49CQWmsqhJQmSs83V2Y1e",
                        Api.get().getSchoolId())
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<OssAttributesResponse>() {

                    @Override
                    public void onCompleted() {

                    }

                    @Override
                    public void onError(Throwable e) {
                        OssAttributesResponse f = new OssAttributesResponse();
                        f.error_code = -2;
                        f.error_msg = e.getMessage();
                        callback.call(f);
                    }

                    @Override
                    public void onNext(OssAttributesResponse ossAttributesResponse) {
                        Slog.d(TAG, "onNext  [ossAttributesResponse]:");
                        callback.call(ossAttributesResponse);
                    }
                });
    }

    /**
     * 获取文件扩展名
     *
     * @param file
     * @return
     */
    public static String getFileExtension(File file) {
        String fileName = file.getName();
        if (fileName.lastIndexOf(".") != -1 && fileName.lastIndexOf(".") != 0) {
            return "." + fileName.substring(fileName.lastIndexOf(".") + 1);
        } else {
            return "";
        }
    }

    /**
     * 转换字符为UTF-8编码
     */
    public static String encodeUTF8(String string) {
        try {
            return URLEncoder.encode(string, "utf-8");
        } catch (UnsupportedEncodingException e) {
            return string;
        }
    }

    public interface ApiCallback {
        void onResult(FileUploadResponse response);

        void onResult(String s);
    }
}
